import allure
import pytest
import time
from utils.conftest import get_test_data
from utils.generate_sql import generate_sql
from utils.gly_write import gly_write
from utils.jdy_list import gly_list
from utils.mysql_util import MysqlDb
from utils.log_util import logger


@allure.feature("新云湖数据同步")
class TestData:
    @pytest.mark.parametrize('app_id,entry_id,sql,fields,months,name', get_test_data())
    def test_main(self, app_id, entry_id, sql, fields, months, name):
        allure.dynamic.title(name)
        logger.info(f"开始测试用例: {name} | 表单ID: {entry_id}")
        start_time = time.time()
        # 步骤1: 清理历史数据
        with allure.step("清理历史数据"):
            jdy_delete = gly_list(app_id=app_id, entry_id=entry_id, fields=fields, months_back=months)
            if jdy_delete != 200:
                pytest.fail(f"删除数据失败 | 状态码：{jdy_delete}")
        # 步骤2: 准备SQL查询
        with allure.step("准备SQL查询"):
            if fields != 'None':
                logger.debug(f"构建动态SQL:表单ID：{entry_id} | 字段: {fields} | 月份回溯: {months+1}月")
                sql = generate_sql(sql=sql, fields=fields, months_back=months)
            logger.debug(f"最终SQL: {sql[:200]}..." if len(sql) > 200 else f"最终SQL: {sql}")
        # 步骤3: 执行数据库查询
        with allure.step("执行数据库查询"):
            logger.info("开始执行数据库查询")
            try:
                with MysqlDb() as db:
                    result = db.select_all(sql)
                if not result:
                    logger.warning("数据库查询结果为空")
                    pytest.skip("数据库查询结果为空")
                record_count = len(result)
                logger.info(f"数据库查询完成: 表单ID：{entry_id} | 获取到 {record_count} 条记录")
            except Exception as e:
                logger.error(f"数据库查询失败: {str(e)}")
                pytest.fail(f"数据库查询失败: {str(e)}")
        # 步骤4: 写入数据
        with allure.step("写入数据"):
            jdy_write = gly_write(result, app_id, entry_id)
            if jdy_write == 206:
                logger.warning("部分数据写入成功，部分失败")
            if jdy_write not in [200, 206]:
                pytest.fail(f"写入数据失败 | 状态码: {jdy_write}")
        # 测试完成，记录总耗时
        total_time = time.time() - start_time
        logger.info(f"测试用例完成: {name} | 总耗时: {total_time:.2f}秒")
        assert jdy_write == 200, f"写入数据失败 | 状态码：{jdy_write}"
